package com.dengpp.pdform.view;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.hardware.Camera;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;


import com.dengpp.pdform.R;
import com.dengpp.pdform.model.LocationInfo;
import com.dengpp.pdform.model.MediaFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.graphics.Matrix;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;

public class CustomCameraActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback {
    private static final String TAG = "CustomCameraActivity";

    private Camera camera;
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private Button btnCapture;
    private Button btnCancel;
    private TextView tvLocation;
    private TextView tvZoom;

    private LocationManager locationManager;
    private LocationListener locationListener;
    private LocationInfo currentLocation;
    private boolean isLocationReceived = false;

    // 缩放相关
    private ScaleGestureDetector scaleGestureDetector;
    private float currentZoomLevel = 1.0f;
    private float minZoomLevel = 1.0f;
    private float maxZoomLevel = 1.0f;

    // 广角/普通
    private Button btnSwitchCamera;
    private boolean isWideAngle = false;


    // 相机参数
    private Camera.Parameters parameters;
    private int cameraId = Camera.CameraInfo.CAMERA_FACING_BACK; // 默认后置摄像头

    public static void start(AppCompatActivity activity, int requestCode) {
        Intent intent = new Intent(activity, CustomCameraActivity.class);
        activity.startActivityForResult(intent, requestCode);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_camera);

        initViews();
        initScaleGestureDetector();
        startLocationUpdates();
    }

    private void initViews() {
        surfaceView = findViewById(R.id.surface_view);
        btnCapture = findViewById(R.id.btn_capture);
        btnCancel = findViewById(R.id.btn_cancel);
        btnSwitchCamera = findViewById(R.id.btn_switch_camera); // 新增按钮
        tvLocation = findViewById(R.id.tv_location);
        tvZoom = findViewById(R.id.tv_zoom);

        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        btnCapture.setOnClickListener(v -> captureImage());
        btnCancel.setOnClickListener(v -> finish());
        btnSwitchCamera.setOnClickListener(v -> switchCamera()); // 摄像头切换
    }

    /**
     * 切换摄像头
     */
    private void switchCamera() {
        if (camera != null) {
            camera.stopPreview();
            camera.release();
            camera = null;
        }

        // 切换摄像头ID
        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            cameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
        } else {
            cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
        }

        // 重新初始化相机
        initCamera();

        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
        } catch (IOException e) {
            Log.e(TAG, "切换摄像头后预览失败", e);
        }
    }

    private void initScaleGestureDetector() {
        scaleGestureDetector = new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
            private float initialZoom;

            @Override
            public boolean onScaleBegin(ScaleGestureDetector detector) {
                initialZoom = currentZoomLevel;
                return true;
            }

            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                float scaleFactor = detector.getScaleFactor();

                // 使用对数缩放，让缩放更自然
                if (scaleFactor > 1) {
                    // 放大
                    currentZoomLevel = initialZoom + (scaleFactor - 1) * 10;
                } else {
                    // 缩小
                    currentZoomLevel = initialZoom - (1 - scaleFactor) * 10;
                }

                // 限制缩放范围
                currentZoomLevel = Math.max(minZoomLevel, Math.min(currentZoomLevel, maxZoomLevel));

                // 应用缩放
                applyZoom();

                return true;
            }

            @Override
            public void onScaleEnd(ScaleGestureDetector detector) {
                // 缩放结束，可以添加一些清理工作
            }
        });
    }

    private void initCamera() {
        try {
            // 尝试打开后置摄像头
            camera = Camera.open(cameraId);

            if (camera == null) {
                // 如果后置摄像头失败，尝试前置摄像头
                cameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
                camera = Camera.open(cameraId);
            }

            if (camera == null) {
                throw new RuntimeException("无法打开相机");
            }

            // 获取初始参数
            Camera.Parameters initialParams = camera.getParameters();

            // 设置各种参数
            setOptimalPreviewSize(initialParams);
            setPictureSize(initialParams);
            setFocusMode(initialParams);
            setupZoom(initialParams);

            // 应用参数
            if (!setCameraParametersSafely(initialParams)) {
                Log.w(TAG, "初始参数设置失败，使用默认参数");
            }

            // 设置相机方向
            setCameraDisplayOrientation();

        } catch (Exception e) {
            Log.e(TAG, "初始化相机失败", e);
            Toast.makeText(this, "无法打开相机", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    /**
     * 设置最佳预览尺寸
     */
    private void setOptimalPreviewSize(Camera.Parameters params) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int screenWidth = displayMetrics.widthPixels;
        int screenHeight = displayMetrics.heightPixels;

        List<Camera.Size> supportedPreviewSizes = params.getSupportedPreviewSizes();
        Camera.Size optimalSize = getOptimalPreviewSize(supportedPreviewSizes, screenWidth, screenHeight);

        if (optimalSize != null) {
            params.setPreviewSize(optimalSize.width, optimalSize.height);
            Log.d(TAG, "设置预览尺寸: " + optimalSize.width + "x" + optimalSize.height);
        }
    }

    /**
     * 设置图片尺寸
     */
    private void setPictureSize(Camera.Parameters params) {
        List<Camera.Size> supportedPictureSizes = params.getSupportedPictureSizes();
        Camera.Size optimalPictureSize = getOptimalPreviewSize(supportedPictureSizes, 1920, 1080);

        if (optimalPictureSize != null) {
            params.setPictureSize(optimalPictureSize.width, optimalPictureSize.height);
            Log.d(TAG, "设置图片尺寸: " + optimalPictureSize.width + "x" + optimalPictureSize.height);
        }
    }

    /**
     * 设置对焦模式
     */
    private void setFocusMode(Camera.Parameters params) {
        List<String> focusModes = params.getSupportedFocusModes();
        if (focusModes != null) {
            if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                Log.d(TAG, "设置连续对焦模式");
            } else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                Log.d(TAG, "设置自动对焦模式");
            } else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) {
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
                Log.d(TAG, "设置固定对焦模式");
            }
        }
    }

    /**
     * 设置缩放参数
     */
    private void setupZoom(Camera.Parameters params) {
        if (params.isZoomSupported()) {
            maxZoomLevel = params.getMaxZoom();
            minZoomLevel = 0;
            currentZoomLevel = 0;
            Log.d(TAG, "缩放支持: 最大级别 " + maxZoomLevel);
        } else {
            maxZoomLevel = 0;
            minZoomLevel = 0;
            currentZoomLevel = 0;
            Log.d(TAG, "不支持缩放");
        }
        updateZoomText();
    }

    /**
     * 应用缩放
     */
    private void applyZoom() {
        if (parameters != null && parameters.isZoomSupported()) {
            try {
                // 创建新的参数对象
                Camera.Parameters newParams = camera.getParameters();

                // 计算缩放级别
                int zoomLevel = (int) currentZoomLevel;
                zoomLevel = Math.max(0, Math.min(zoomLevel, newParams.getMaxZoom()));

                // 设置缩放
                newParams.setZoom(zoomLevel);

                // 应用参数
                camera.setParameters(newParams);

                // 更新显示
                updateZoomText();
            } catch (Exception e) {
                Log.e(TAG, "设置缩放失败", e);
            }
        }
    }

    /**
     * 更新缩放文本
     */
    private void updateZoomText() {
        if (tvZoom != null) {
            tvZoom.setText(String.format("缩放: %.1fx", currentZoomLevel));
        }
    }

    /**
     * 设置相机显示方向
     */
    private void setCameraDisplayOrientation() {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);

        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // 补偿镜像
        } else {
            result = (info.orientation - degrees + 360) % 360;
        }

        camera.setDisplayOrientation(result);
    }

    /**
     * 获取最佳预览尺寸
     */
    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;

        if (sizes == null) return null;

        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        for (Camera.Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    private void startLocationUpdates() {
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }

        locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                if (location != null) {
                    currentLocation = new LocationInfo(location.getLatitude(), location.getLongitude());
                    isLocationReceived = true;
                    updateLocationText();
                    Log.d(TAG, "位置更新: " + currentLocation.toString());
                }
            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
            }

            @Override
            public void onProviderEnabled(String provider) {
            }

            @Override
            public void onProviderDisabled(String provider) {
            }
        };

        // 请求位置更新
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 1, locationListener);

        // 获取最后一次已知位置
        Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (lastKnownLocation == null) {
            lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }

        if (lastKnownLocation != null) {
            currentLocation = new LocationInfo(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
            isLocationReceived = true;
            updateLocationText();
        }
    }

    /**
     * 更新位置文本
     */
    private void updateLocationText() {
        if (tvLocation != null && currentLocation != null) {
            tvLocation.setText(String.format("位置: %.6f, %.6f",
                    currentLocation.getLatitude(), currentLocation.getLongitude()));
        }
    }

    private void captureImage() {
        if (camera != null) {
            camera.takePicture(null, null, new Camera.PictureCallback() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    saveImage(data);
                    camera.startPreview(); // 重新开始预览
                }
            });
        }
    }

    private void saveImage(byte[] data) {
        try {
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
            String fileName = "IMG_" + timeStamp + ".jpg";

            File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            if (storageDir == null) {
                storageDir = getFilesDir();
            }

            File imageFile = new File(storageDir, fileName);
            FileOutputStream fos = new FileOutputStream(imageFile);
            fos.write(data);
            fos.close();

            // 创建MediaFile对象
            MediaFile mediaFile = new MediaFile(imageFile.getAbsolutePath(), MediaFile.MediaType.IMAGE);
            mediaFile.setName("自定义相机_" + timeStamp);

            // 添加位置信息
            if (isLocationReceived && currentLocation != null) {
                mediaFile.setLocationInfo(currentLocation);
            }

            // 返回结果
            Intent resultIntent = new Intent();
            resultIntent.putExtra("media_file", mediaFile);
            setResult(RESULT_OK, resultIntent);
            finish();

        } catch (IOException e) {
            Log.e(TAG, "保存图片失败", e);
            Toast.makeText(this, "保存图片失败", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        initCamera();
        try {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
        } catch (IOException e) {
            Log.e(TAG, "设置相机预览失败", e);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (surfaceHolder.getSurface() == null) {
            return;
        }

        try {
            camera.stopPreview();

            // 重新设置相机方向
            setCameraDisplayOrientation();

            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();

        } catch (Exception e) {
            Log.e(TAG, "重新开始预览失败", e);

            // 如果预览失败，尝试重新初始化相机
            try {
                reinitializeCameraParameters();
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();
            } catch (Exception ex) {
                Log.e(TAG, "恢复预览也失败", ex);
                Toast.makeText(this, "相机预览失败", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 清理资源在onDestroy中处理
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        // 预览帧回调，可用于实时处理
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 处理缩放手势
        scaleGestureDetector.onTouchEvent(event);

        // 处理点击对焦
        if (event.getAction() == MotionEvent.ACTION_UP) {
            handleFocus(event);
        }

        return true;
    }

    /**
     * 处理点击对焦
     */
    private void handleFocus(MotionEvent event) {
        if (camera == null) return;

        try {
            // 获取当前参数
            Camera.Parameters currentParams = camera.getParameters();

            // 检查是否支持对焦区域
            if (currentParams.getMaxNumFocusAreas() > 0) {
                Rect focusRect = calculateTapArea(event.getX(), event.getY(), 1f);
                List<Camera.Area> focusAreas = new ArrayList<>();
                focusAreas.add(new Camera.Area(focusRect, 1000));

                // 创建新的参数对象，避免修改正在使用的参数
                Camera.Parameters newParams = camera.getParameters();
                newParams.setFocusAreas(focusAreas);

                // 检查并设置对焦模式
                List<String> supportedFocusModes = newParams.getSupportedFocusModes();
                if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
                    newParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                }

                // 应用新参数
                camera.setParameters(newParams);
                camera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        // 对焦完成回调
                        if (success) {
                            Log.d(TAG, "对焦成功");
                        } else {
                            Log.d(TAG, "对焦失败");
                        }
                    }
                });
            }
        } catch (Exception e) {
            Log.e(TAG, "对焦失败", e);
            // 如果对焦失败，尝试简单的自动对焦
            trySimpleAutoFocus();
        }
    }

    /**
     * 尝试简单的自动对焦
     */
    private void trySimpleAutoFocus() {
        try {
            if (camera != null) {
                camera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        Log.d(TAG, "简单对焦" + (success ? "成功" : "失败"));
                    }
                });
            }
        } catch (Exception e) {
            Log.e(TAG, "简单对焦也失败", e);
        }
    }

    /**
     * 计算点击区域
     */
    private Rect calculateTapArea(float x, float y, float coefficient) {
        int focusAreaSize = 300;
        int areaSize = (int) (focusAreaSize * coefficient);

        int left = clamp((int) (x - areaSize / 2), 0, surfaceView.getWidth() - areaSize);
        int top = clamp((int) (y - areaSize / 2), 0, surfaceView.getHeight() - areaSize);

        RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
        Matrix matrix = new Matrix();
        matrix.setRotate(0);
        matrix.mapRect(rectF);

        return new Rect(Math.round(rectF.left), Math.round(rectF.top),
                Math.round(rectF.right), Math.round(rectF.bottom));
    }

    private int clamp(int x, int min, int max) {
        if (x > max) return max;
        if (x < min) return min;
        return x;
    }

    /**
     * 安全设置相机参数
     */
    private boolean setCameraParametersSafely(Camera.Parameters params) {
        try {
            camera.setParameters(params);
            this.parameters = params; // 更新当前参数引用
            return true;
        } catch (RuntimeException e) {
            Log.e(TAG, "设置相机参数失败: " + e.getMessage());

            // 尝试使用基本参数重新设置
            try {
                Camera.Parameters basicParams = camera.getParameters();
                // 只设置必要的参数
                basicParams.setPreviewSize(params.getPreviewSize().width, params.getPreviewSize().height);
                basicParams.setPictureSize(params.getPictureSize().width, params.getPictureSize().height);
                camera.setParameters(basicParams);
                this.parameters = basicParams;
                return true;
            } catch (Exception ex) {
                Log.e(TAG, "恢复基本参数也失败", ex);
                return false;
            }
        }
    }

    /**
     * 重新初始化相机参数（当参数设置失败时调用）
     */
    private void reinitializeCameraParameters() {
        try {
            if (camera != null) {
                Camera.Parameters newParams = camera.getParameters();

                // 重新设置基本参数
                setOptimalPreviewSize(newParams);
                setPictureSize(newParams);
                setFocusMode(newParams);
                setupZoom(newParams);

                // 应用参数
                if (setCameraParametersSafely(newParams)) {
                    setCameraDisplayOrientation();
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "重新初始化相机参数失败", e);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // 释放相机资源
        if (camera != null) {
            camera.stopPreview();
            camera.release();
            camera = null;
        }

        // 移除位置监听
        if (locationManager != null && locationListener != null) {
            locationManager.removeUpdates(locationListener);
        }
    }
}
